package com.twq.patternmatch.basic

/**
 * Created by tangweiqun on 2017/11/22.
 */

//表示算术表达式
//sealed abstract class Expr
abstract class Expr

//表示变量
case class Var(name: String) extends Expr

//表示数字
case class Number(num: Double) extends Expr

//表示一元操作
case class UnOp(operator: String, arg: Expr) extends Expr

//表示二元操作
case class BinOp(operator: String,
                 left: Expr, right: Expr) extends Expr

//单例对象
case object SingletonObj extends Expr

/**
 * case class 讲解
 */
object ArithmeticExpressions {
  def main(args: Array[String]): Unit = {
    //1: 如果一个类的类体是空的话，我们可以将{}去掉

    //2: 用case修饰的Class 我们称之为Case Class。编译器看到这个case修饰的class，会为这个class加一些额外的特性：

    //2.1、编译器会为Case Class增加一个以类名为名字的工厂方法，这个工厂方法作用是构建这个类的对象
    val v = Var("x") //构建对象的时候不需要用new关键词
    //这个特性在需要利用嵌套类来构建对象的时候特别方便，比如：
    val op = BinOp("+", Number(1), v)

    //2.2、编译器默认的为case class的值参数加上了val来进行修饰，所以这些值参数和一个类里的域一样
    v.name
    op.left

    //2.3、编译器自动为case class添加了toString、hashCode以及equals方法
    println(op)
    //可以用 == 来比较case class，比较case class的类型以及case class中的值参数
    op.right == Var("x")

    //2.4、编译器为case class增加了一个copy方法，使得case class的值参数的值可以修改
    //如果一个case class中只要几个特定的值参数需要改变的话，用copy比较方便
    val opNew = op.copy(operator = "-")


    //3、case 除了可以修饰class，还可以修饰object，就是表示一个单例对象

    //4、case class最大的优点就是配合模式匹配
  }
}
